package builder;

import java.util.ArrayList;
import java.util.List;

/**
 * 这篇目前是基本全抄的 菜鸟教程并简化的 2022.12.05
 *
 * 参考: 菜鸟教程-设计模式: https://www.runoob.com/design-pattern/builder-pattern.html
 *
 * 问题 1: 官方定义是什么? 自己理解又是什么?
 * 官方定义: 建造者模式（Builder Pattern）使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式，它提供了一种创建对象的最佳方式。
 * 自己理解: 我认为就是基础的东西不常变, 但排列组合会有较大变化时, 则会使用建造者模式;
 * 换句话说, 建造者模式更多是为了控制物品排列组合顺序
 *
 * 问题 2: 为了解决什么问题
 * 一些基本部件不会变，而其组合经常变化的时候。
 *
 * 问题 3: 优缺点是什么
 *
 * 问题 4: 有什么典型的应用例子
 * 1、去肯德基，汉堡、可乐、薯条、炸鸡翅等是不变的，而其组合是经常变化的，生成出所谓的"套餐"。 2、JAVA 中的 StringBuilder。
 */

public class BuilderPattern {

    // 使用 MealBuilder 来演示建造者模式
    public static void main(String[] args) {
        MealBuilder mealBuilder = new MealBuilder();

        Meal vegMeal = mealBuilder.prepareVegMeal();
        System.out.println("Veg Meal");
        vegMeal.showItems();
        System.out.println("Total Cost: " + vegMeal.getCost());

        Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
        System.out.println("\n\nNon-Veg Meal");
        nonVegMeal.showItems();
        System.out.println("Total Cost: " + nonVegMeal.getCost());
    }

}

interface Item {
    public String name();
    public float price();
}


abstract class Burger implements Item {
    @Override
    public abstract float price();
}

abstract class ColdDrink implements Item {
    @Override
    public abstract float price();
}

// 创建扩展了 Burger 和 ColdDrink 的实体类
class VegBurger extends Burger {

    @Override
    public float price() {
        return 25.0f;
    }

    @Override
    public String name() {
        return "Veg Burger";
    }
}

class ChickenBurger extends Burger {

    @Override
    public float price() {
        return 50.5f;
    }

    @Override
    public String name() {
        return "Chicken Burger";
    }
}

class Coke extends ColdDrink {

    @Override
    public float price() {
        return 30.0f;
    }

    @Override
    public String name() {
        return "Coke";
    }
}

class Pepsi extends ColdDrink {

    @Override
    public float price() {
        return 35.0f;
    }

    @Override
    public String name() {
        return "Pepsi";
    }
}


// 创建一个 Meal 类, 带有上面定义的 item 对象;
class Meal {
    private List<Item> items = new ArrayList<Item>();

    public void addItem(Item item){
        items.add(item);
    }

    public float getCost(){
        float cost = 0.0f;
        for (Item item : items) {
            cost += item.price();
        }
        return cost;
    }

    public void showItems(){
        for (Item item : items) {
            System.out.print("Item : "+item.name());
            System.out.println(", Price : "+item.price());
        }
    }
}


// 创建一个 MealBuilder 类, 实际的 builder 类负责创建 Meal 对象;
class MealBuilder {

    public Meal prepareVegMeal (){
        Meal meal = new Meal();
        meal.addItem(new VegBurger());
        meal.addItem(new Coke());
        return meal;
    }

    public Meal prepareNonVegMeal (){
        Meal meal = new Meal();
        meal.addItem(new ChickenBurger());
        meal.addItem(new Pepsi());
        return meal;
    }
}